/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package person.location;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.el.ELContext;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;
import org.postgis.Point;
import org.primefaces.model.map.DefaultMapModel;
import org.primefaces.model.map.LatLng;
import org.primefaces.model.map.MapModel;
import org.primefaces.model.map.Marker;
import system.general.Exc;
import system.general.Logged;
import system.general.Message;
import system.general.Persistencia;

/**
 *
 * @author emojica
 */
@ManagedBean(name = "person_location")
@ViewScoped
public class Main extends Beans implements Serializable {
    //Variables de importación General

    Logged logged;
    private Persistencia persistencia = new Persistencia();
    private Message msg = new Message();
    //Variables de importación otros modulos
    //Variables del modulo
    private Find person_locationFind = new Find();
    private List<Beans> person_locationList = new ArrayList<>();
    //Variables locales
    private String sql;
    private Map<String, String> map = new LinkedHashMap<>();
    private MapModel emptyModel;
    private Marker marker;
    private Double lat = 8.932509021104444;
    private Double lng = -79.8275537603455;

    public Main() {
        ELContext elContext = FacesContext.getCurrentInstance().getELContext();
        logged = (Logged) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "logged");
        emptyModel = new DefaultMapModel();
    }

    public void load() {
        try {
            map.clear();
            map.put("l.id  = " + logged.getDetailId(), " ");

            person_locationList.clear();
            person_locationList = person_locationFind.byMap(map);

            setId(person_locationList.get(0).getId());
            setIdl_tipo(person_locationList.get(0).getIdl_tipo());
            setId_Corregimiento(person_locationList.get(0).getId_Corregimiento());
            getTownshipBeans().setNombre(person_locationList.get(0).getTownshipBeans().getNombre());
            getDistrictBeans().setId(person_locationList.get(0).getDistrictBeans().getId());
            getDistrictBeans().setNombre(person_locationList.get(0).getDistrictBeans().getNombre());
            getProvinceBeans().setId(person_locationList.get(0).getProvinceBeans().getId());
            getProvinceBeans().setNombre(person_locationList.get(0).getProvinceBeans().getNombre());
            getCountryBeans().setId(person_locationList.get(0).getCountryBeans().getId());
            getCountryBeans().setNombre(person_locationList.get(0).getCountryBeans().getNombre());
            setDireccion(person_locationList.get(0).getDireccion());
            setGeometry(person_locationList.get(0).getGeometry());
            Point p = new Point(getGeometry().getValue());
            setLng(p.getX());
            setLat(p.getY());


        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public void insert() throws Exc, SQLException, Exception {
        try {
            //Verifica si se ha seleccionado un registro
            if (logged.getMasterId() == 0) {
                throw new Exc("m21");
            }

            //carga el mapa con lo valores de la llave unica
            map.clear();
            map.put("id_persona = " + logged.getMasterId(), " AND ");
            map.put("idl_tipo = " + getIdl_tipo(), " AND ");
            map.put("id_corregimiento = " + getId_Corregimiento(), " AND ");
            map.put("lower(direccion) = '" + getDireccion().toLowerCase() + "'", " ");

            //Verifica si el registro existe, de lo contrario lo inserta
            if (person_locationFind.byExist(map)) {
                throw new Exc("m5");
            }

            sql = "INSERT INTO public.persona_localizacion (id_persona, idl_tipo, id_corregimiento, direccion, geometry) "
                    + "VALUES (" + logged.getMasterId() + "," + getIdl_tipo() + "," + getId_Corregimiento() + ",'" + getDireccion() + "',ST_GeomFromText('POINT(" + getLng() + " " + getLat() + ")',4326))";

            //Inserta la información del registro
            persistencia.executeUpdate(sql);

            //Localiza el id del registro recien insertado, con la llave única
            person_locationList = person_locationFind.byMap(map);

            //Asigna el id del registro insertado a la variable global
            logged.setDetailId(person_locationList.get(0).getId());

        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }

    }

    public void update() {
        try {
            if (logged.getMasterId() == 0) {
                throw new Exc("m4");
            }
            //Verifica si hay registros seleccionados
            if (logged.getDetailId() == 0) {
                throw new Exc("m6");
            }

            //Verifica si el registro existe, de lo contrario lo inserta
            map.clear();
            map.put("l.id <> " + logged.getDetailId(), " AND ");
            map.put("id_persona = " + logged.getMasterId(), " AND ");
            map.put("idl_tipo = " + getIdl_tipo(), " AND ");
            map.put("id_corregimiento = " + getId_Corregimiento(), " AND ");
            map.put("lower(direccion) = '" + getDireccion().toLowerCase() + "'", " ");

            //Verifica si el registro existe, de lo contrario lo inserta
            if (person_locationFind.byExist(map)) {
                throw new Exc("m5");
            }

            Point p = (Point) getGeometry().getGeometry();
            sql = "UPDATE public.persona_localizacion SET "
                    + "id_persona = " + logged.getMasterId() + ", "
                    + "idl_tipo = " + getIdl_tipo() + ", "
                    + "id_corregimiento = " + getId_Corregimiento() + ", "
                    + "direccion='" + getDireccion() + "', "
                    + "geometry = ST_GeomFromText('POINT(" + getLng() + " " + getLat() + ")',4326)"
                    + " WHERE id =" + logged.getDetailId();

            //Actualiza la información del registro
            persistencia.executeUpdate(sql);

            throw new Exc("m2");

        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public void delete() {
        try {

            //Verifica si hay registros seleccionados
            if (logged.getDetailId() == 0) {
                throw new Exc("m4");
            }

            //Elimina el resgistro por el id_persona
            deleteById(logged.getDetailId());

            logged.setDetailId(0);
            clear();

            throw new Exc("m3");

        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public void deleteById(int id) throws Exc, SQLException, Exception {
        //Verifica si el usuario ya existe para otra persona
        sql = "DELETE FROM public.persona_localizacion "
                + "WHERE id = " + id;
        persistencia.executeUpdate(sql);
    }

    public void clear() {
        clearBeans();
        setLat(8.932509021104444);
        setLng(-79.8275537603455);
    }

    public void insertCountry() throws Exc, SQLException, Exception {
        location.general.Main paisMain = new location.general.Main();
        getCountryBeans().setId(paisMain.insert(getCountryBeans().getNombre()));
        getCountryBeans().setNombre("");
    }

    public void insertProvince() throws Exc, SQLException, Exception {
        location.province.Main cityMain = new location.province.Main();
        getProvinceBeans().setId(cityMain.insert(getCountryBeans().getId(), getProvinceBeans().getNombre()));
        getProvinceBeans().setNombre("");
    }

    public void insertDistrict() throws Exc, SQLException, Exception {
        location.district.Main distritoMain = new location.district.Main();
        getDistrictBeans().setId(distritoMain.insert(getProvinceBeans().getId(), getDistrictBeans().getNombre()));
        getDistrictBeans().setNombre("");
    }

    public void insertTownship() throws Exc, SQLException, Exception {
        location.township.Main townshipMain = new location.township.Main();
        setId_Corregimiento(townshipMain.insert(getDistrictBeans().getId(), getTownshipBeans().getNombre()));
        getTownshipBeans().setNombre("");
    }

    public void selectedCountry(ValueChangeEvent event) {
        getCountryBeans().setId(Integer.parseInt(event.getNewValue().toString()));
    }

    public void selectedProvince(ValueChangeEvent event) {
        getProvinceBeans().setId(Integer.parseInt(event.getNewValue().toString()));
    }

    public void selectedDistric(ValueChangeEvent event) {
        getDistrictBeans().setId(Integer.parseInt(event.getNewValue().toString()));
    }

    public void selectedTownship(ValueChangeEvent event) {
        setId_Corregimiento(Integer.parseInt(event.getNewValue().toString()));
    }

    public MapModel getEmptyModel() {
        return emptyModel;
    }

    public void addMarker(ActionEvent actionEvent) {
        Point point = (Point) getGeometry().getGeometry();
        emptyModel.getMarkers().clear();
        marker = new Marker(new LatLng(point.getX(), point.getY()));
        emptyModel.addOverlay(marker);
    }

    public Marker getMarker() {
        return marker;
    }

    public void selectedTempId(int tempId) {
        logged.setDetailId(tempId);
        load();
    }

    private String namePackage() {
        Package pack = this.getClass().getPackage();
        return pack.getName();
    }

    public Double getLat() {
        return lat;
    }

    public void setLat(Double lat) {
        this.lat = lat;
    }

    public Double getLng() {
        return lng;
    }

    public void setLng(Double lng) {
        this.lng = lng;
    }
}
